<?php
/*
Extension Name: Sitemaps
Extension Url: http://lussumo.com/docs/
Description: Generates an sitemaps.xml file of all discussion and account URLs on the forum
Version: 0.1
Author: David Kitchen (buro9 on vanilla.com)
Author Url: http://www.buro9.com/
*/

class Sitemaps {

  var $Name;
  var $Context;

  function Sitemaps(&$Context) {
    $this->Name = "Sitemaps";
    $this->Context = &$Context;
  }

  function Render() {
    //
    // CONFIGURATION : START
    //
    $renderCustomUrls = TRUE;
    $renderDiscussions = TRUE;
    $renderUsers = TRUE;

    //
    // Define the custom URLs by inserting arrays encapsulating that URLs
    // properties into the $customUrl array.
    // 
    // URLs can take all of the following IN THE ORDER SPECIFIED, only the URL
    // itself is mandatory.
    // 
    // array($url, $lastUpdated, $changeFrequency, $priority);
    // 
    // $url = Absolute URL as a browser sees it; http://www.londonfgss.com/categories/
    // $lastUpdated = W3C Date format; 2007-04-23 21:22:08
    // $changeFrequency = One of the following; always, hourly, daily, weekly, monthly,
    //       yearly, never
    // $priority = Valid values range from 0.0 to 1.0. This is a relative thing according
    //       to what you deem most valuable on your site. Setting everything to the same
    //       value negates the usefulness of this. Default value is 0.5
    //
    $customUrls = array(
      array('http://forum.php-ids.org/', date('Y-m-d H:i:s', mktime()), 'hourly', 1.0),
      array('http://forum.php-ids.org/?CategoryID=1'),
      array('http://forum.php-ids.org/?CategoryID=2'),
      array('http://forum.php-ids.org/?CategoryID=3'),
      array('http://forum.php-ids.org/?CategoryID=4'),
      array('http://forum.php-ids.org/?CategoryID=5'),
      array('http://forum.php-ids.org/?CategoryID=6'),
      array('http://forum.php-ids.org/?CategoryID=7'),
      array('http://forum.php-ids.org/?CategoryID=8'),
      array('http://forum.php-ids.org/?CategoryID=9'),
      array('http://forum.php-ids.org/?CategoryID=10'),
      array('http://forum.php-ids.org/extension.php?PostBackAction=GoogleMapDirectory'),
    );

    //
    // CONFIGURATION : END
    // 
    // Nothing useful to edit beyond this point unless you really know what
    // you're doing.
    //
    function RenderUrlNode($url, $lastUpdated = '', $changeFrequency = 'daily', $priority = 0.5) {
      $now = mktime();
      if ($lastUpdated == '') {
        $lastUpdated = date('c', $now);
      } else {
        //
        // Smart frequency, according to when last updated
        //
        if ($changeFrequency == 'daily') {
          if (UnixTimestamp($lastUpdated) > ($now - 86400)) {
            $changeFrequency = 'daily';
          } elseif (UnixTimestamp($lastUpdated) > ($now - 86400*7)) {
            $changeFrequency = 'weekly';
          } elseif (UnixTimestamp($lastUpdated) > ($now - 86400*28)) {
            $changeFrequency = 'monthly';
          } else {
            $changeFrequency = 'yearly';
          }
        }
        $lastUpdated = date('c', UnixTimestamp($lastUpdated));
      }

      //
      // Smart priority, according to frequency of update.
      //
      if ($priority == 0.5) {
        switch ($changeFrequency) {
          case 'always':
            $priority = 1.0;
            break;
          case 'hourly':
            $priority = 0.8;
            break;
          case 'daily':
            $priority = 0.7;
            break;
          case 'weekly':
            $priority = 0.6;
            break;
          case 'monthly':
            $priority = 0.5;
            break;
          case 'yearly':
            $priority = 0.3;
            break;
          case 'never':
            $priority = 0.2;
            break;
          default:
            $changeFrequency = 'daily';
            $priority = 0.5;
            break;
        }
      }

      return "<url>\n\t<loc>$url</loc>\n\t<lastmod>$lastUpdated</lastmod>\n\t<changefreq>$changeFrequency</changefreq>\n\t<priority>$priority</priority>\n</url>\n";
    }
  
    echo "<?xml version='1.0' encoding='UTF-8'?>\n<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>\n";
    
    //
    // Get the custom URL's
    //
    if ($renderCustomUrls) {
      for ($ii = 0; $ii < count($customUrls); $ii++) {
        $customUrl = $customUrls[$ii];
        switch (count($customUrl)) {
          case 1:
            echo RenderUrlNode($customUrl[0]);
            break;
          case 2:
            echo RenderUrlNode($customUrl[0], $customUrl[1]);
            break;
          case 3:
            echo RenderUrlNode($customUrl[0], $customUrl[1], $customUrl[2]);
            break;
          case 4:
            echo RenderUrlNode($customUrl[0], $customUrl[1], $customUrl[2], $customUrl[3]);
            break;
          default:
            break;
        }
      }
    }
    
    //
    // Get the Discussions
    //
    if ($renderDiscussions) {
      $sql = $this->Context->ObjectFactory->NewContextObject($this->Context, "SqlBuilder");
      $sql->SetMainTable("Discussion", "d");
      $sql->AddSelect(array("DiscussionID", "DateLastActive", "Name", "CountComments"), "d");
      $sql->AddWhere("d", "WhisperUserID", "", "0", "=", NULL, NULL, 0);
      $sql->AddOrderBy("DiscussionID", "d");
    
      $discussions = $this->Context->Database->Select(
        $sql,
        $this->Name,
        "GetDiscussions",
        "An error occurred while attempting to retrieve the Discussions."
      );
    
      if ($this->Context->Database->RowCount($discussions) == 0) {
        return NULL;
      } else {
        while ($discussion = $this->Context->Database->GetRow($discussions)) {
          for ($ii = 1; $ii <= ceil($discussion["CountComments"] / 50); $ii++) {
            $sitemapUrl = GetUrl(
              $this->Context->Configuration,
              "comments.php",
              "",
              "DiscussionID",
              ForceInt($discussion["DiscussionID"], 0),
              $ii,
              '',
              CleanupString($discussion["Name"]).'/'
            );
            echo RenderUrlNode($sitemapUrl, @$discussion["DateLastActive"]);
          }
        }
      }
    }
    
    //
    // Get the Users
    //
    if ($renderUsers) {
      $sql = $this->Context->ObjectFactory->NewContextObject($this->Context, "SqlBuilder");
      $sql->SetMainTable("User", "u");
      $sql->AddSelect(array("UserID", "DateLastActive", "Name"), "u");
      $sql->AddOrderBy("UserID", "u");
    
      $users = $this->Context->Database->Select(
        $sql,
        $this->Name,
        "GetUsers",
        "An error occurred while attempting to retrieve the Users."
      );
    
      if ($this->Context->Database->RowCount($users) == 0) {
        return NULL;
      } else {
        while ($user = $this->Context->Database->GetRow($users)) {
          $sitemapUrl = GetUrl(
            $this->Context->Configuration,
            "account.php",
            "",
            "UserID",
            ForceInt($user["UserID"], 0)
          );
          echo RenderUrlNode($sitemapUrl, @$user["DateLastActive"]);
        }
      }
    }

    echo '</urlset>';
    exit;
  }
}

if ($Context->SelfUrl == 'extension.php' && $_GET['PostBackAction'] == 'sitemap.xml') {
  $Sitemaps = $Context->ObjectFactory->NewContextObject($Context, "Sitemaps");
  $Sitemaps->Render();
}

?>
